package notice.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * @description: MQ扣款结果通知交换机、队列配置
 * @author: zk
 * @since: 2022-08-16 15:09
 */
@Slf4j
@Configuration
public class MQDeductionConfig {
    // MQ扣款结果通知交换机
    public static final String EXCHANGE_DEDUCTION_NOTICE = "exchange_deduction_notice";
    // MQ扣款结果通知死信交换机
    public static final String DEATH_EXCHANGE_DEDUCTION_NOTICE = "death_exchange_deduction_notice";
    // MQ扣款结果通知队列
    public static final String QUEUE_DEDUCTION_NOTICE = "queue_deduction_notice";
    // MQ扣款结果通知死信队列
    public static final String DEATH_QUEUE_DEDUCTION_NOTICE = "death_queue_deduction_notice";
    // MQ扣款结果通知 ROUTING_KEY
    public static final String ROUTING_KEY_DEDUCTION_NOTICE = "deduction.notice";
    // MQ扣款结果通知死信 ROUTING_KEY
    public static final String ROUTING_KEY_DEATH_NOTICE = "death.notice";
    // 分隔符
    public static final String ROUTING_KEY_ONE = "*";
    public static final String ROUTING_KEY_ALL = "#";
    public static final String SEPARATE = ".";

    /**
     * 交换机配置
     *
     * @return the exchange
     */
    @Bean(EXCHANGE_DEDUCTION_NOTICE)
    public Exchange eductionNoticeExchange() {
        //durable(true)持久化，消息队列重启后交换机仍然存在
        return ExchangeBuilder.topicExchange(EXCHANGE_DEDUCTION_NOTICE)// mq中交换机的别名
                .durable(true)
                .build();
    }

    /**
     * 队列配置
     *
     * @return the queue
     */
    @Bean(QUEUE_DEDUCTION_NOTICE)
    public Queue eductionNoticeQueue() {
        //durable(true)持久化，消息队列重启后队列仍然存在
        Map<String, Object> map = new HashMap<>();
        // 死信发给哪个交换机
        map.put("x-dead-letter-exchange", DEATH_EXCHANGE_DEDUCTION_NOTICE);
        // 死信使用的routing-key = death.notice.cumulate
        map.put("x-dead-letter-routing-key", ROUTING_KEY_DEATH_NOTICE + SEPARATE + "cumulate");
        return new Queue(QUEUE_DEDUCTION_NOTICE, true, false, false, map);
    }

    /**
     * 队列绑定交换机
     * 通配符：
     * Routingkey 一般都是有一个或多个单词组成，多个单词之间以”.”分割
     * #：匹配一个或多个词
     * *：匹配不多不少恰好1个词
     *
     * @param queue
     * @param exchange
     * @return
     */
    @Bean
    public Binding bindingQueue2Exchange(@Qualifier(QUEUE_DEDUCTION_NOTICE) Queue queue,
                                         @Qualifier(EXCHANGE_DEDUCTION_NOTICE) Exchange exchange) {
        return BindingBuilder.bind(queue).to(exchange)
                // eduction.notice.#
                .with(ROUTING_KEY_DEDUCTION_NOTICE + SEPARATE + ROUTING_KEY_ALL)
                .noargs();
    }

    /**
     * 死信交换机配置
     *
     * @return the exchange
     */
    @Bean(DEATH_EXCHANGE_DEDUCTION_NOTICE)
    public Exchange exchangeDeath() {
        return ExchangeBuilder.topicExchange(DEATH_EXCHANGE_DEDUCTION_NOTICE)
                .durable(true)
                .build();
    }

    /**
     * 死信队列
     *
     * @return the queue
     */
    @Bean(DEATH_QUEUE_DEDUCTION_NOTICE)
    public Queue queueDeath() {
        Queue queue = new Queue(DEATH_QUEUE_DEDUCTION_NOTICE, true);
        return queue;
    }

    /**
     * 死信队列绑定交换机
     *
     * @param queue
     * @param exchange
     * @return
     */
    @Bean
    public Binding bindingDeathQueue2Exchange(@Qualifier(DEATH_QUEUE_DEDUCTION_NOTICE) Queue queue,
                                              @Qualifier(DEATH_EXCHANGE_DEDUCTION_NOTICE) Exchange exchange) {
        return BindingBuilder.bind(queue).to(exchange)
                // death.notice.#
                .with(ROUTING_KEY_DEATH_NOTICE + SEPARATE + ROUTING_KEY_ALL)
                .noargs();
    }


}